import plugin from '../../../lib/plugins/plugin.js'
import fetch from 'node-fetch'
import fs from "fs"
import path from "path"
import data from '../model/XiuxianData.js'
import Config from "../model/Config.js"
import { segment } from "oicq"
import { get_player_img, get_najie_img} from './showData.js'

//插件根目录
const __dirname = path.resolve() + path.sep + "plugins" + path.sep + "xiuxian-emulator-plugin";
// 文件存放路径
export const __PATH = {
    //用户数据
    player_path: path.join(__dirname, "/resources/data/xiuxian_player"),
    //装备
    equipment_path: path.join(__dirname, "/resources/data/xiuxian_equipment"),
    //纳戒
    najie_path: path.join(__dirname, "/resources/data/xiuxian_najie"),
    //源数据
    lib_path: path.join(__dirname, "/resources/data/item"),
    //公告数据
    log_path: path.join(__dirname, "/logs"),
}


/**
 * 全局
 */
let allaction = false;//全局状态判断
let xiuxianSetFile = "./plugins/xiuxian-emulator-plugin/config/xiuxian/xiuxian.yaml";
if (!fs.existsSync(xiuxianSetFile)) {
    fs.copyFileSync("./plugins/xiuxian-emulator-plugin/defSet/xiuxian/xiuxian.yaml", xiuxianSetFile);
}


//处理消息
export class xiuxian extends plugin {
    constructor() {
        super({
            /** 功能名称 */
            name: 'Yunzai_Bot_xiuxian',
            /** 功能描述 */
            dsc: '修仙模块',
            event: 'message',
            /** 优先级，数字越小等级越高 */
            priority: 800,
            rule: [
                {
                    reg: '^#踏入仙途$',
                    fnc: 'Create_player'
                },
                {
                    reg: '^#(修仙重生|再入仙途|重新修仙)$',
                    fnc: 'reCreate_player'
                },
                {
                    reg: '^#(我的存档|我的信息)$',
                    fnc: 'Show_player'
                },
                {
                    reg: '^#我的纳戒$',
                    fnc: 'Show_najie'
                },
                {
                    reg: '^#(升级纳戒|纳戒升级)$',
                    fnc: 'Lv_up_najie'
                },
                {
                    reg: '^#(改名.*)|(设置道宣.*)$',
                    fnc: 'Change_player_name'
                },
                {
                    reg: '^#修仙签到$',
                    fnc: 'daily_gift'
                },
                {
                    reg: '^#(最近公告|福利记录)$',
                    fnc: 'last_Log'
                }
            ]
        })
        this.xiuxianConfigData = Config.getConfig("xiuxian", "xiuxian");
    }





    //#踏入仙途
    async Create_player(e) {
        let usr_qq = e.user_id;
        //判断是否为匿名创建存档
        if (usr_qq == 80000000) {
            e.reply("不支持匿名创建存档");
            return;
        }
        //有无存档
        let ifexistplay = await existplayer(usr_qq);
        if (ifexistplay) {
            e.reply("已经有存档了");
            this.Show_player(e);
            return;
        }
        //初始化玩家信息
        let File_msg = fs.readdirSync(__PATH.player_path);
        let n = File_msg.length + 1;
        let talent = await get_random_talent();
        let new_player = {
            "名号": `路人甲${n}号`,
            "灵根": talent,
            "境界": "江湖草莽",
            "修为": 0,
            "灵石": 200,
            "学习的功法": [],
            "宣言": "这个人很懒还没有写",
            "修炼效率提升": talent.eff,
            "连续签到天数": 0,
            //根据表来赋予基础信息
            "基础血量": data.Level_list.find(item => item.level == "江湖草莽").基础血量,
            "基础防御": data.Level_list.find(item => item.level == "江湖草莽").基础防御,
            "基础攻击": data.Level_list.find(item => item.level == "江湖草莽").基础攻击,
            "基础暴击": data.Level_list.find(item => item.level == "江湖草莽").基础暴击,
            "当前血量": 1
        }
        await Write_player(usr_qq, new_player);

        //初始化装备
        let new_equipment = {
            "武器": data.equipment_list.find(item => item.name == "烂铁匕首"),
            "护具": data.equipment_list.find(item => item.name == "破铜护具"),
            "法宝": data.equipment_list.find(item => item.name == "廉价炮仗")
        }
        await Write_equipment(usr_qq, new_equipment);

        //初始化纳戒
        let new_najie = {
            "等级": 1,
            "灵石上限": 5000,
            "灵石": 0,
            "装备": [],
            "丹药": [],
            "道具": [],
            "功法": [],
            "草药": []
        }
        await Write_najie(usr_qq, new_najie);
        await Add_HP(usr_qq, 999999);
        this.Show_player(e);
        return;
    }


    //重新修仙
    async reCreate_player(e) {
        let usr_qq = e.user_id;
        //有无存档
        let ifexistplay = await existplayer(usr_qq);
        if (!ifexistplay) {
            e.reply("没存档你重生个锤子!");
            return;
        }
        //重生之前先看状态

        await Go(e);
        if (allaction) {
            console.log(allaction);
        }
        else {
            return;
        }
        allaction = false;



        let now = new Date();
        let nowTime = now.getTime(); //获取当前时间戳
        let lastrestart_time = await redis.get("xiuxian:player:" + usr_qq + ":last_reCreate_time");//获得上次重生时间戳,
        
        lastrestart_time = parseInt(lastrestart_time);
        console.log("lastrestart_time", lastrestart_time);
        var time=this.xiuxianConfigData.CD.reborn;
        let rebornTime = parseInt(60000 * time )
        console.log("lastrestart_time", lastrestart_time);
        if (nowTime < lastrestart_time + rebornTime) {
            let waittime_m = Math.trunc((lastrestart_time + rebornTime - nowTime) / 60 / 1000);
            let waittime_s = Math.trunc(((lastrestart_time + rebornTime - nowTime) % 60000) / 1000);
            e.reply(`每${rebornTime / 60 / 1000}分钟只能重生一次` + `剩余cd:${waittime_m}分 ${waittime_s}秒`);
            return;
        }
        /** 设置上下文 */
        this.setContext('RE_xiuxian');
        /** 回复 */
        await e.reply('一旦重生一切从头开始,你真的要重生吗?回复:【重生】或者【算了】进行选择', false, { at: true });
        return;
    }


    //重生方法
    async RE_xiuxian(e) {
        let usr_qq = e.user_id;
        /** 内容 */
        let new_msg = this.e.message;
        let choice = new_msg[0].text;
        let now = new Date();
        let nowTime = now.getTime(); //获取当前时间戳
        if (choice == "算了") {

            await this.reply('放弃重生,继续修行');
            /** 结束上下文 */
            this.finish('RE_xiuxian');
            return;
        }
        else if (choice == "重生") {
            //关闭仙门
            redis.set("xiuxian:player:" + usr_qq + ":power_place", 1);

            //重生牵扯到宗门模块
            let player = await data.getData("player", usr_qq);
            if (isNotNull(player.宗门)) {
                if (player.宗门.职位 != "宗主") {//不是宗主
                    let ass = data.getAssociation(player.宗门.宗门名称);
                    ass[player.宗门.职位] = ass[player.宗门.职位].filter(item => item != usr_qq);
                    ass["所有成员"] = ass["所有成员"].filter(item => item != usr_qq);//原来的成员表删掉这个B
                    await data.setAssociation(ass.宗门名称, ass);
                    delete player.宗门;
                    await data.setData("player", usr_qq, player);
                    console.log("退出宗门成功");
                }
                else {//是宗主
                    let ass = data.getAssociation(player.宗门.宗门名称);
                    if (ass.所有成员.length < 2) {
                        console.log("只有宗主一个人,直接删除宗门");
                        fs.rmSync(`${data.filePathMap.association}/${player.宗门.宗门名称}.json`);
                    }
                    else {
                        ass["所有成员"] = ass["所有成员"].filter(item => item != usr_qq);//原来的成员表删掉这个B
                        //随机一个幸运儿的QQ,优先挑选等级高的
                        let randmember_qq;
                        if (ass.长老.length > 0) { randmember_qq = await get_random_fromARR(ass.长老); }
                        else if (ass.内门弟子.length > 0) { randmember_qq = await get_random_fromARR(ass.内门弟子); }
                        else { randmember_qq = await get_random_fromARR(ass.所有成员); }

                        let randmember = await data.getData("player", randmember_qq);//获取幸运儿的存档
                        ass[randmember.宗门.职位] = ass[randmember.宗门.职位].filter((item) => item != randmember_qq);//原来的职位表删掉这个幸运儿
                        ass["宗主"] = randmember_qq;//新的职位表加入这个幸运儿
                        randmember.宗门.职位 = "宗主";//成员存档里改职位
                        await data.setData("player", randmember_qq, randmember);//记录到存档
                        await data.setAssociation(ass.宗门名称, ass);//记录到宗门
                    }
                    console.log("退出宗门成功");
                }

            }
            fs.rmSync(`${__PATH.player_path}/${usr_qq}.json`);
            fs.rmSync(`${__PATH.equipment_path}/${usr_qq}.json`);
            fs.rmSync(`${__PATH.najie_path}/${usr_qq}.json`);
            e.reply([segment.at(usr_qq), "当前存档已清空!开始重生"]);
            e.reply([segment.at(usr_qq), "来世，信则有，不信则无，岁月悠悠，世间终会出现两朵相同的花，千百年的回眸，一花凋零，一花绽。是否为同一朵，任后人去评断"]);
            await this.Create_player(e);
            redis.set("xiuxian:player:" + usr_qq + ":last_reCreate_time", nowTime);//redis设置本次改名时间戳

        }
        else {
            this.setContext('RE_xiuxian');
            await this.reply('请回复:【重生】或者【算了】进行选择', false, { at: true });
            return;
        }
        /** 结束上下文 */
        this.finish('RE_xiuxian');
        return;
    }

    //#我的存档
    async Show_player(e) {
        let usr_qq = e.user_id;
        //有无存档
        let ifexistplay = await existplayer(usr_qq);
        if (!ifexistplay) {
            return;
        }
        let img = await get_player_img(e);
        e.reply(img);
        return;
    }


    //#我的纳戒
    async Show_najie(e) {
        let usr_qq = e.user_id;
        //有无存档
        let ifexistplay = await existplayer(usr_qq);
        if (!ifexistplay) {
            return;
        }
        let img = await get_najie_img(e);
        e.reply(img);
        return;
    }


    //Lv_up_najie纳戒升级
    async Lv_up_najie(e) {
        let usr_qq = e.user_id;
        //有无存档
        let ifexistplay = await existplayer(usr_qq);



        if (!ifexistplay) { return; }

        await Go(e);
        if (allaction) {
            console.log(allaction);
        }
        else {
            return;
        }
        allaction = false;



        let najie = await Read_najie(usr_qq);
        let player = await Read_player(usr_qq);
        let najie_num = this.xiuxianConfigData.najie_num
        let najie_price = this.xiuxianConfigData.najie_price
        if (najie.等级 == najie_num.length) {
            e.reply("你的纳戒已经是最高级的了")
            return;
        }
        if (player.灵石 < najie_price[najie.等级]) {
            e.reply(`灵石不足,还需要准备${najie_price[najie.等级] - player.灵石}灵石`)
            return;
        }
        await Add_灵石(usr_qq, -najie_price[najie.等级]);
        najie.灵石上限 = najie_num[najie.等级];
        najie.等级 += 1;
        //console.log(najie);
        await Write_najie(usr_qq, najie);
        e.reply(`你的纳戒升级成功,花了${najie_price[najie.等级 - 1]}灵石,目前纳戒灵石存储上限为${najie.灵石上限},可以使用【#我的纳戒】来查看`)
        return;
    }


    //改名
    async Change_player_name(e) {
        let usr_qq = e.user_id;
        //有无存档
        let ifexistplay = await existplayer(usr_qq);
        if (!ifexistplay) {
            return;
        }
        //检索方法
        var reg = new RegExp(/改名|设置道宣/);
        let func = reg.exec(e.msg);

        //
        if (func == "改名") {
            let new_name = e.msg.replace("#改名", '');
            new_name = new_name.replace(" ", '');
            new_name = new_name.replace("+", '');
            if (new_name.length == 0) {
                e.reply("改名格式为:【#改名张三】请输入正确名字");
                return;
            }
            else if (new_name.length > 8) {
                e.reply("玩家名字最多八字");
                return;
            }
            var name=["尼玛","你妈","艹","我操","操你","麻痹","妈逼","丢你","老母","公龟"];
            for(var i=0;i<name.height;i++){
                var x=new_name.indexOf(name[i]);
                if(x!=-1){
                    return;
                }
            }
            let player = {};
            let now = new Date();
            let nowTime = now.getTime(); //获取当前日期的时间戳
            //let Yesterday = await shijianc(nowTime - 24 * 60 * 60 * 1000);//获得昨天日期
            let Today = await shijianc(nowTime);
            let lastsetname_time = await redis.get("xiuxian:player:" + usr_qq + ":last_setname_time");//获得上次改名日期,
            lastsetname_time = parseInt(lastsetname_time);
            lastsetname_time = await shijianc(lastsetname_time);


            console.log(Today.Y)
            console.log(lastsetname_time.Y)
            console.log(Today.M)
            console.log(lastsetname_time.M)
            console.log(Today.D)
            console.log(lastsetname_time.D)
            if (Today.Y == lastsetname_time.Y && Today.M == lastsetname_time.M && Today.D == lastsetname_time.D) {
                e.reply("每日只能改名一次");
                return;
            }
            player = await Read_player(usr_qq);
            if (player.灵石 < 100) {
                e.reply("改名需要100灵石");
                return;
            }
            player.名号 = new_name;
            redis.set("xiuxian:player:" + usr_qq + ":last_setname_time", nowTime);//redis设置本次改名时间戳
            player.灵石 -= 100;
            await Write_player(usr_qq, player);
            //Add_灵石(usr_qq, -100);
            this.Show_player(e);
            return;
        }

        //设置道宣
        else if (func == "设置道宣") {
            let new_msg = e.msg.replace("#设置道宣", '');
            new_msg = new_msg.replace(" ", '');
            new_msg = new_msg.replace("+", '');
            if (new_msg.length == 0) {
                e.reply("设道宣格式为:【#设道宣我要成仙】");
                return;
            }
            else if (new_msg.length > 50) {
                e.reply("道宣最多50字符");
                return;
            }

            let player = {};
            let now = new Date();
            let nowTime = now.getTime(); //获取当前日期的时间戳
            //let Yesterday = await shijianc(nowTime - 24 * 60 * 60 * 1000);//获得昨天日期
            //
            let Today = await shijianc(nowTime);
            let lastsetxuanyan_time = await redis.get("xiuxian:player:" + usr_qq + ":last_setxuanyan_time");
            //获得上次改道宣日期,
            lastsetxuanyan_time = parseInt(lastsetxuanyan_time);
            lastsetxuanyan_time = await shijianc(lastsetxuanyan_time);

            if (Today.Y == lastsetxuanyan_time.Y && Today.M == lastsetxuanyan_time.M && Today.D == lastsetxuanyan_time.D) {
                e.reply("每日只能设置一次道宣");
                return;
            }
            
            //这里有问题，写不进去
            player = await Read_player(usr_qq);
            player.宣言 = new_msg;//
            redis.set("xiuxian:player:" + usr_qq + ":last_setxuanyan_time", nowTime);//redis设置本次设道置宣时间戳
            await Write_player(usr_qq, player);
            this.Show_player(e);
            return;
        }
    }


    //签到
    async daily_gift(e) {
        let usr_qq = e.user_id;
        //有无账号
        let ifexistplay = await existplayer(usr_qq);
        if (!ifexistplay) {
            return;
        }
        let now = new Date();
        let nowTime = now.getTime(); //获取当前日期的时间戳
        let Yesterday = await shijianc(nowTime - 24 * 60 * 60 * 1000);//获得昨天日期
        let Today = await shijianc(nowTime);
        let lastsign_time = await getLastsign(usr_qq);//获得上次签到日期
        if (Today.Y == lastsign_time.Y && Today.M == lastsign_time.M && Today.D == lastsign_time.D) {
            e.reply(`今日已经签到过了`);
            return;
        }
        let Sign_Yesterday;        //昨日日是否签到
        if (Yesterday.Y == lastsign_time.Y && Yesterday.M == lastsign_time.M && Yesterday.D == lastsign_time.D) {
            Sign_Yesterday = true;
        }
        else {
            Sign_Yesterday = false;
        }
        await redis.set("xiuxian:player:" + usr_qq + ":lastsign_time", nowTime);//redis设置签到时间
        let player = await data.getData("player", usr_qq);
        if (player.连续签到天数 == 7 || !Sign_Yesterday) {//签到连续7天或者昨天没有签到,连续签到天数清零
            player.连续签到天数 = 0;
        }
        player.连续签到天数 += 1;
        await data.setData("player", usr_qq, player);
        //给奖励
        let gift_lingshi = player.连续签到天数 * 500;
        let gift_xiuwei = player.连续签到天数 * 300;
        await Add_灵石(usr_qq, gift_lingshi);
        await Add_修为(usr_qq, gift_xiuwei);
        let msg = [
            segment.at(usr_qq),
            `已经连续签到${player.连续签到天数}天了,获得了${gift_lingshi}灵石,获得了${gift_xiuwei}修为`
        ]
        e.reply(msg);
        return;
    }


    //最近公告
    async last_Log(e) {
        let log_msg = await get_log();
        e.reply(log_msg);
        return;
    }

    //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓按理来讲这个括号在我的vscode是黄色的
}


/**
 * 状态
 */

 export async function Go(e) {
    let usr_qq = e.user_id;
    //有无存档
    let ifexistplay = await existplayer(usr_qq);
    if (!ifexistplay) {
        return;
    }
    //获取游戏状态
    let game_action = await redis.get("xiuxian:player:" + usr_qq + ":game_action");
    //防止继续其他娱乐行为
    if (game_action == 0) {
        e.reply("修仙：游戏进行中...");
        return;
    }
    //查询redis中的人物动作
    let action = await redis.get("xiuxian:player:" + usr_qq + ":action");
    action = JSON.parse(action);
    if (action != null) {
        //人物有动作查询动作结束时间
        let action_end_time = action.end_time;
        let now_time = new Date().getTime();
        if (now_time <= action_end_time) {
            let m = parseInt((action_end_time - now_time) / 1000 / 60);
            let s = parseInt(((action_end_time - now_time) - m * 60 * 1000) / 1000);
            e.reply("正在" + action.action + "中,剩余时间:" + m + "分" + s + "秒");
            return;
        }
    }
    let player = await Read_player(usr_qq);
    if (player.当前血量 < 200) {
        e.reply("你都伤成这样了,就不要出去浪了");
        return;
    }
    allaction = true;
    return;
}



const 伪灵根概率 = 0.6;
const 真灵根概率 = 0.35;
const 天灵根概率 = 0.03;
const 变异灵根概率 = 1 - 伪灵根概率 - 真灵根概率 - 天灵根概率;

//写入log信息
export async function set_log(data) {
    //获取时间
    let now = new Date();
    let nowTime = now.getTime(); //获取当前日期的时间戳
    let logfile = [];
    let nowlog = {
        time: timestampToTime(nowTime),
        content: data,
    }
    let dir = path.join(`${__PATH.log_path}/xiuxian_log.json`);
    logfile = fs.readFileSync(dir, 'utf8');
    logfile = JSON.parse(logfile);
    logfile.unshift(nowlog);
    let logARR = JSON.stringify(logfile, "", "\t");
    fs.writeFileSync(dir, logARR, 'utf8');
    return;
}

//读取log信息
export async function get_log() {
    let dir = path.join(`${__PATH.log_path}/xiuxian_log.json`);
    let logfile = fs.readFileSync(dir, 'utf8');
    logfile = JSON.parse(logfile);
    let log_length = 10;
    if (logfile.length < 10) {
        log_length = logfile.length;
    }
    let msg = [];

    if (!isNotNull(logfile[0])) {
        msg.push(`暂时没有记录`);
    }
    else {
        msg.push(`最近${log_length}条记录:`);
        for (var i = 0; i < log_length; i++) {
            msg.push("\n" + `[${logfile[i].time}]${logfile[i].content}`);
        }
    }

    return msg;
}

//渡劫
export async function dujieup(e, x, i,n,m) {
    //获取信息
    let usr_qq = e.user_id;
    let player = await Read_player(usr_qq);
    //随机获得雷截
    var y = Math.random() * (m - n) - n;
    //每道雷在原来的基础上加到最高0.9
    y = y + i * 0.1;
    //设置不能最高
    if (y > m) { y = m }
    //开始反馈雷截情况
    if (x >= y) {
        e.reply("雷劫从天而下，你度过雷截！");
        return i;//反馈当前雷截
    }
    else 
    {
        e.reply("此时，雷劫大变，竟然是灭世之雷！轰隆一声巨响，雷劫迅速击落，你坚持不到一息，昏厥在地...");
        player.当前血量 = 0;//渡劫失败，血量清空
        player.修为 = 0;//渡劫失败，修为清空
        Write_player(usr_qq, player);
        return 0;//反馈0，渡劫失败了！
    }
}





//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//以下方法调用时不加await很可能不同步导致出错

//检查存档是否存在，存在返回true;
export async function existplayer(usr_qq) {
    let exist_player;
    exist_player = fs.existsSync(`${__PATH.player_path}/${usr_qq}.json`);
    if (exist_player) {
        return true;
    }
    return false;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//读取存档信息，返回成一个JavaScript对象
export async function Read_player(usr_qq) {
    let dir = path.join(`${__PATH.player_path}/${usr_qq}.json`);
    let player = fs.readFileSync(dir, 'utf8', (err, data) => {
        if (err) {
            console.log(err)
            return "error";
        }
        return data;
    })
    //将字符串数据转变成数组格式
    player = JSON.parse(player);
    return player;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//写入存档信息,第二个参数是一个JavaScript对象
export async function Write_player(usr_qq, player) {
    let dir = path.join(__PATH.player_path, `${usr_qq}.json`);
    let new_ARR = JSON.stringify(player, "", "\t");
    fs.writeFileSync(dir, new_ARR, 'utf8', (err) => {
        console.log('写入成功', err)
    })
    return;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//读取装备信息，返回成一个JavaScript对象
export async function Read_equipment(usr_qq) {
    let dir = path.join(`${__PATH.equipment_path}/${usr_qq}.json`);
    let equipment = fs.readFileSync(dir, 'utf8', (err, data) => {
        if (err) {
            console.log(err)
            return "error";
        }
        return data;
    })
    //将字符串数据转变成数组格式
    equipment = JSON.parse(equipment);
    return equipment;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//写入装备信息,第二个参数是一个JavaScript对象
export async function Write_equipment(usr_qq, equipment) {
    //每次写入都要更新新的攻防生
    let equ_atk = equipment.武器.atk + equipment.护具.atk + equipment.法宝.atk;
    let equ_def = equipment.武器.def + equipment.护具.def + equipment.法宝.def;
    let equ_HP = equipment.武器.HP + equipment.护具.HP + equipment.法宝.HP;
    let equ_bao = equipment.武器.bao + equipment.护具.bao + equipment.法宝.bao;
    let player = await Read_player(usr_qq);
    player["攻击"] = equ_atk + player.基础攻击;
    player["防御"] = equ_def + player.基础防御;
    player["血量上限"] = equ_HP + player.基础血量;
    player["暴击率"] = equ_bao + player.基础暴击;
    await Write_player(usr_qq, player);
    await Add_HP(usr_qq, 0);
    let dir = path.join(__PATH.equipment_path, `${usr_qq}.json`);
    let new_ARR = JSON.stringify(equipment, "", "\t");
    fs.writeFileSync(dir, new_ARR, 'utf8', (err) => {
        console.log('写入成功', err)
    })
    return;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//读取纳戒信息，返回成一个JavaScript对象
export async function Read_najie(usr_qq) {
    let dir = path.join(`${__PATH.najie_path}/${usr_qq}.json`);
    let najie = fs.readFileSync(dir, 'utf8', (err, data) => {
        if (err) {
            console.log(err)
            return "error";
        }
        return data;
    })
    //将字符串数据转变成数组格式
    najie = JSON.parse(najie);
    return najie;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//写入纳戒信息,第二个参数是一个JavaScript对象
export async function Write_najie(usr_qq, najie) {
    let dir = path.join(__PATH.najie_path, `${usr_qq}.json`);
    let new_ARR = JSON.stringify(najie, "", "\t");
    fs.writeFileSync(dir, new_ARR, 'utf8', (err) => {
        console.log('写入成功', err)
    })
    return;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//修为数量和灵石数量正增加,负减少
//使用时记得加await
export async function Add_灵石(usr_qq, 灵石数量 = 0) {
    let player = await Read_player(usr_qq);
    player.灵石 += Math.trunc(灵石数量);
    await Write_player(usr_qq, player);
    return;
}
export async function Add_修为(usr_qq, 修为数量 = 0) {
    let player = await Read_player(usr_qq);
    player.修为 += Math.trunc(修为数量);
    await Write_player(usr_qq, player);
    return;
}
export async function Add_HP(usr_qq, blood = 0) {
    let player = await Read_player(usr_qq);
    player.当前血量 += Math.trunc(blood);
    if (player.当前血量 > player.血量上限) {
        player.当前血量 = player.血量上限;
    }
    await Write_player(usr_qq, player);
    return;
}
export async function Add_najie_灵石(usr_qq, lingshi) {
    let najie = await Read_najie(usr_qq);
    najie.灵石 += Math.trunc(lingshi);
    await Write_najie(usr_qq, najie);
    return;
}

export async function Add_player_学习功法(usr_qq, gongfa_name) {
    let player = await Read_player(usr_qq);
    player.学习的功法.push(gongfa_name);
    await data.setData("player", usr_qq, player);
    await player_efficiency(usr_qq);
    return;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//修炼效率综合
export async function player_efficiency(usr_qq) {
    console.log('计算天赋')
    let player = await data.getData("player", usr_qq);//修仙个人信息
    let ass;
    let Assoc_efficiency;        //宗门效率加成
    let linggen_efficiency;      //灵根效率加成
    let gongfa_efficiency = 0;  //功法效率加成

    if (!isNotNull(player.宗门)) {//是否存在宗门信息
        Assoc_efficiency = 0;  //不存在，宗门效率为0
    } else {
        ass = await data.getAssociation(player.宗门.宗门名称);//修仙对应宗门信息
        Assoc_efficiency = ass.宗门等级 * 0.05;
    }
    if (!isNotNull(player.灵根)) {//是否存在灵根，判断老存档
        player.灵根 = await get_random_talent();//不存在灵根，获取灵根
    }
    linggen_efficiency = player.灵根.eff;//灵根修炼速率
    if (!isNotNull(player.学习的功法)) {//是否存在功法
        gongfa_efficiency = 0;    //不存在功法，功法效率为0
    }
    else {
        for (var i = 0; i < player.学习的功法.length; i++) { //存在功法，遍历功法加成
            let gongfa_name = player.学习的功法[i];
            //这里是查看了功法表
            let ifexist2 = data.gongfa_list.find(item => item.name == gongfa_name);
            //如果表里不存在这个功法了
            if (!ifexist2) {
                //找到这个功法的位置
                let ceshi = player.学习的功法.indexOf(gongfa_name);
                //删除这个位置
                if (ceshi > -1) {
                    player.学习的功法.splice(ceshi, 1);
                }
                //删除完成后删除
                break;
            }
            //如果存在就是合理了
            gongfa_efficiency += ifexist2.修炼加成;
        }
    }
    if (parseInt(player.修炼效率提升) != parseInt(player.修炼效率提升)) {
        player.修炼效率提升 = 0;
    }
    player.修炼效率提升 = linggen_efficiency + Assoc_efficiency + gongfa_efficiency;//修炼效率综合
    console.log(player.修炼效率提升);
    console.log(Math.trunc(player.修炼效率提升));
    await data.setData("player", usr_qq, player);
    return;
}

//检查纳戒内物品是否存在
//判断物品
//要用await
export async function exist_najie_thing(usr_qq, thing_name, thing_class) {
    console.log("检查戒指");
    let najie = await Read_najie(usr_qq);

    if (!isNotNull(najie.草药)) {
        najie.草药 = [];
    }
    await Write_najie(usr_qq, najie);
    let ifexist;
    if (thing_class == "装备") {
        ifexist = najie.装备.find(item => item.name == thing_name);
    }
    if (thing_class == "丹药") {
        ifexist = najie.丹药.find(item => item.name == thing_name);
    }
    if (thing_class == "道具") {
        ifexist = najie.道具.find(item => item.name == thing_name);
    }
    if (thing_class == "功法") {
        ifexist = najie.功法.find(item => item.name == thing_name);
    }
    if (thing_class == "草药") {
        ifexist = najie.草药.find(item => item.name == thing_name);
    }
    //console.log(ifexist.数量);
    if (ifexist) {
        return ifexist.数量;
    }
    return false;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


/**
 * 增加减少纳戒内物品
 * @param usr_qq 操作存档的qq号
 * @param thing_name  物品名称 
 * @param thing_class  物品类别
 * @param n  操作的数量,取+增加,取 -减少
 * @returns 无
 */
export async function Add_najie_thing(usr_qq, thing_name, thing_class, n) {
    if (n === 0) {
        n = 1
    };//调整为1
    if (n == 0) {
        n = 1
    };//调整为1
    var x = n;
    let najie = await Read_najie(usr_qq);
    var name = thing_name;
    if (!isNotNull(najie.草药)) {//判断老存档有没有草药字段
        najie.草药 = [];
    }
    //写入
    await Write_najie(usr_qq, najie);
    let exist = await exist_najie_thing(usr_qq, name, thing_class);
    //这部分写得很冗余,但能跑
    if (thing_class == "装备") {
        //失败
        if (x > 0 && !exist) {//无中生有
            najie.装备.push(data.equipment_list.find(item => item.name == name));
            najie.装备.find(item => item.name == name).数量 = x;
            await Write_najie(usr_qq, najie);
            return;
        }
        //记录数量
        najie.装备.find(item => item.name == name).数量 += x;
        //
        if (najie.装备.find(item => item.name == name).数量 < 1) {
            //假如用完了,需要删掉数组中的元素,用.filter()把!=该元素的过滤出来
            najie.装备 = najie.装备.filter(item => item.name != name);
        }
        await Write_najie(usr_qq, najie);
        return;
    }
    if (thing_class == "丹药") {
        if (x > 0 && !exist) {//无中生有
            najie.丹药.push(data.danyao_list.find(item => item.name == name));
            najie.丹药.find(item => item.name == name).数量 = x;
            await Write_najie(usr_qq, najie);
            return;
        }
        najie.丹药.find(item => item.name == name).数量 += x;
        if (najie.丹药.find(item => item.name == name).数量 < 1) {
            //假如用完了,需要删掉数组中的元素,用.filter()把!=该元素的过滤出来
            najie.丹药 = najie.丹药.filter(item => item.name != name);
        }
        await Write_najie(usr_qq, najie);
        return;
    }
    if (thing_class == "道具") {
        if (x > 0 && !exist) {//无中生有
            najie.道具.push(data.daoju_list.find(item => item.name == name));
            najie.道具.find(item => item.name == name).数量 = x;
            await Write_najie(usr_qq, najie);
            return;
        }
        najie.道具.find(item => item.name == name).数量 += x;
        if (najie.道具.find(item => item.name == name).数量 < 1) {
            //假如用完了,需要删掉数组中的元素,用.filter()把!=该元素的过滤出来
            najie.道具 = najie.道具.filter(item => item.name != name);
        }
        await Write_najie(usr_qq, najie);
        return;
    }
    if (thing_class == "功法") {
        if (x > 0 && !exist) {//无中生有
            najie.功法.push(data.gongfa_list.find(item => item.name == name));
            najie.功法.find(item => item.name == name).数量 = x;
            await Write_najie(usr_qq, najie);
            return;
        }
        najie.功法.find(item => item.name == name).数量 += x;
        if (najie.功法.find(item => item.name == name).数量 < 1) {
            //假如用完了,需要删掉数组中的元素,用.filter()把!=该元素的过滤出来
            najie.功法 = najie.功法.filter(item => item.name != name);
        }
        await Write_najie(usr_qq, najie);
        return;
    }
    if (thing_class == "草药") {
        if (x > 0 && !exist) {//无中生有
            najie.草药.push(data.caoyao_list.find(item => item.name == name));
            najie.草药.find(item => item.name == name).数量 = x;
            await Write_najie(usr_qq, najie);
            return;
        }
        najie.草药.find(item => item.name == name).数量 += x;
        if (najie.草药.find(item => item.name == name).数量 < 1) {
            //假如用完了,需要删掉数组中的元素,用.filter()把!=该元素的过滤出来
            najie.草药 = najie.草药.filter(item => item.name != thing_name);
        }
        await Write_najie(usr_qq, najie);
        return;
    }
    return;
}


//替换装备
export async function instead_equipment(usr_qq, thing_name) {
    await Add_najie_thing(usr_qq, thing_name, "装备", -1);
    let thing_type = data.equipment_list.find(item => item.name == thing_name).type;
    let equipment = await Read_equipment(usr_qq);
    if (thing_type == "武器") {
        await Add_najie_thing(usr_qq, equipment.武器.name, "装备", 1);
        equipment.武器 = data.equipment_list.find(item => item.name == thing_name);
        await Write_equipment(usr_qq, equipment);
        return;
    }
    if (thing_type == "护具") {
        await Add_najie_thing(usr_qq, equipment.护具.name, "装备", 1);
        equipment.护具 = data.equipment_list.find(item => item.name == thing_name);
        await Write_equipment(usr_qq, equipment);
        return;
    }
    if (thing_type == "法宝") {
        await Add_najie_thing(usr_qq, equipment.法宝.name, "装备", 1);
        equipment.法宝 = data.equipment_list.find(item => item.name == thing_name);
        await Write_equipment(usr_qq, equipment);
        return;
    }
    return;
}

let isdubo = [];
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//获取A打B的消息，A、B为两个人QQ号，返回一个字符串数组
//A打先手
/*
player ={
    攻击:123,
    防御:123,
    当前血量:123,
    暴击率:0.123,
    名号:"ABC",
    qq:123,
    法球倍率: 0.02

}
*/
export async function Getmsg_battle(A_player, B_player) {
    let now_A_HP = A_player.当前血量;//保留初始血量方便计算最后扣多少血,避免反复读写文件
    let now_B_HP = B_player.当前血量;
    let A_xue = 0;//最后要扣多少血
    let B_xue = 0;


    let cnt = 0;//回合数
    let msg = [];
    while (A_player.当前血量 > 0 && B_player.当前血量 > 0) {
        if (cnt % 2 == 0) {
            let baoji = baojishanghai(A_player.暴击率);
            let 伤害 = Harm(A_player.攻击, B_player.防御);
            let 法球伤害 = Math.trunc(A_player.攻击 * A_player.法球倍率);
            伤害 = Math.trunc(baoji * 伤害 + 法球伤害);
            B_player.当前血量 -= 伤害;
            if (B_player.当前血量 < 0) { B_player.当前血量 = 0 }
            msg.push(`第${Math.trunc(cnt / 2) + 1}回合：
${A_player.名号}攻击了${B_player.名号}，${ifbaoji(baoji)}造成伤害${伤害}，造成额外伤害${法球伤害}，${B_player.名号}剩余血量${B_player.当前血量}`);
        }
        if (cnt % 2 == 1) {
            let baoji = baojishanghai(B_player.暴击率);
            let 伤害 = Harm(B_player.攻击, A_player.防御);
            let 法球伤害 = Math.trunc(B_player.攻击 * B_player.法球倍率);
            伤害 = Math.trunc(baoji * 伤害 + 法球伤害);
            A_player.当前血量 -= 伤害;
            if (A_player.当前血量 < 0) { A_player.当前血量 = 0 }
            msg.push(`第${Math.trunc(cnt / 2) + 1}回合：
${B_player.名号}攻击了${A_player.名号}，${ifbaoji(baoji)}造成伤害${伤害}，造成额外伤害${法球伤害}，${A_player.名号}剩余血量${A_player.当前血量}`);
        }
        cnt++;
    }
    if (A_player.当前血量 <= 0) {
        msg.push(`${B_player.名号}击败了${A_player.名号}`);
        B_xue = B_player.当前血量 - now_B_HP;
        A_xue = -now_A_HP;
    }
    if (B_player.当前血量 <= 0) {
        msg.push(`${A_player.名号}击败了${B_player.名号}`);
        B_xue = -now_B_HP;
        A_xue = A_player.当前血量 - now_A_HP;
    }
    let Data_nattle = {
        "msg": msg,
        "A_xue": A_xue,
        "B_xue": B_xue
    }
    return Data_nattle;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//通过输入暴击率,返回暴击伤害,不暴击返回1
export function baojishanghai(baojilv) {
    if (baojilv > 1) { baojilv = 1; }//暴击率最高为100%,即1
    let rand = Math.random();
    let bl = 1;
    if (rand < baojilv) {
        bl = baojilv + 2;//这个是暴击伤害倍率//满暴击时暴伤为300%
    }
    return bl;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//通过暴击伤害返回输出用的文本
export function ifbaoji(baoji) {
    if (baoji == 1) { return ""; }
    else { return '触发暴击，'; }
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//攻击攻击防御计算伤害
export function Harm(atk, def) {
    let x;
    let s = atk / def;
    let rand = Math.trunc(Math.random() * 11) / 100 + 0.95;//保留±5%的伤害波动
    if (s < 1) {
        x = 0.1;
    }
    else if (s > 2.5) {
        x = 1;
    }
    else {
        x = 0.6 * s - 0.5;
    }
    x = Math.trunc(x * atk * rand);
    return x;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//色图
export async function setu(e) {
    let url;
    e.reply(`玩命加载图片中,请稍后...   ` + "\n(一分钟后还没有出图片,大概率被夹了,这个功能谨慎使用,机器人容易寄)")
    url = "https://api.lolicon.app/setu/v2?proxy=i.pixiv.re&r18=0";//setu接口地址
    let msg = [];
    let res;
    try {
        let response = await fetch(url);
        res = await response.json();
    } catch (error) {
        console.log('Request Failed', error);
    }
    //console.log(res);
    if (res !== '{}') { console.log('res不为空'); } else { console.log('res为空'); }
    let link = res.data[0].urls.original;//获取图链
    link = link.replace('pixiv.cat', 'pixiv.re');//链接改为国内可访问的域名
    let pid = res.data[0].pid;//获取图片ID
    let uid = res.data[0].uid;//获取画师ID
    let title = res.data[0].title;//获取图片名称
    let author = res.data[0].author;//获取画师名称
    let px = res.data[0].width + '*' + res.data[0].height;//获取图片宽高
    msg.push("User: " + author +
        "\nUid: " + uid +
        "\nTitle: " + title +
        "\nPid: " + pid +
        "\nPx: " + px +
        "\nLink: " + link);
    await sleep(1000);

    //最后回复消息
    e.reply(segment.image(link));
    await ForwardMsg(e, msg);
    return true; //返回true 阻挡消息不再往下
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//发送转发消息
//输入data一个数组,元素是字符串,每一个元素都是一条消息.
export async function ForwardMsg(e, data) {
    //console.log(data);
    let msgList = [];
    for (let i of data) {
        msgList.push({
            message: i,
            nickname: Bot.nickname,
            user_id: Bot.uin,
        });
    }
    if (msgList.length == 1) {
        await e.reply(msgList[0].message);
    }
    else {
        //console.log(msgList);
        await e.reply(await Bot.makeForwardMsg(msgList));
    }
    return;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//对象数组排序
export function sortBy(field) {//从大到小,b和a反一下就是从小到大
    return function (b, a) {
        return a[field] - b[field];
    }
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//获取总修为
export async function Get_xiuwei(usr_qq) {
    let player = await Read_player(usr_qq);
    let sum_exp = 0;
    let level_id = data.Level_list.find(temp => temp.level == player.境界).level_id;
    if (level_id < 46) {
        for (var i = 1; i < level_id; i++) {
            sum_exp = sum_exp + data.Level_list.find(temp => temp.level_id == i).exp;
        }
    }
    else { sum_exp = -999999999; }//说明玩家境界有错误
    sum_exp += player.修为;
    return sum_exp;
}



//获取随机灵根
export async function get_random_talent() {
    let talent;
    if (get_random_res(伪灵根概率)) {
        talent = data.talent_list.filter(item => item.type == "伪灵根");
    }
    else if (get_random_res(真灵根概率 / (1 - 伪灵根概率))) {
        talent = data.talent_list.filter(item => item.type == "真灵根");
    }
    else if (get_random_res(天灵根概率 / (1 - 真灵根概率 - 伪灵根概率))) {
        talent = data.talent_list.filter(item => item.type == "天灵根");
    }
    else {
        talent = data.talent_list.filter(item => item.type == "变异灵根");
    }
    let newtalent = get_random_fromARR(talent)
    console.log("获得灵根", newtalent);
    return newtalent;
}

//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/**
 * 输入概率随机返回布尔类型数据
 * @param P 概率
 * @returns 随机返回 false or true
 */
 export function get_random_res(P) {
    if (P > 1) { P = 1; }
    if (P < 0) { P = 0; }
    //console.log(P);
    let rand = Math.random();
    //console.log(rand);
    if (rand < P) {
        return true;
    }
    return false;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/**
 * 输入数组随机返回其中一个
 * @param ARR 输入的数组
 * @returns 随机返回一个元素
 */
export function get_random_fromARR(ARR) {
    //let L = ARR.length;
    let randindex = Math.trunc(Math.random() * ARR.length);
    console.log("数组:", randindex)

    return ARR[randindex];
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//sleep
export async function sleep(time) {
    return new Promise(resolve => {
        setTimeout(resolve, time);
    })
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// 时间转换
export function timestampToTime(timestamp) {
    var date = new Date(timestamp);//时间戳为10位需*1000，时间戳为13位的话不需乘1000
    var Y = date.getFullYear() + '-';
    var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
    var D = date.getDate() + ' ';
    var h = date.getHours() + ':';
    var m = date.getMinutes() + ':';
    var s = date.getSeconds();
    return Y + M + D + h + m + s;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//根据时间戳获取年月日时分秒
export async function shijianc(time) {
    let dateobj = {}
    var date = new Date(time)
    dateobj.Y = date.getFullYear()
    dateobj.M = date.getMonth() + 1
    dateobj.D = date.getDate()
    dateobj.h = date.getHours()
    dateobj.m = date.getMinutes()
    dateobj.s = date.getSeconds()
    //let nowTime = `${dateobj.Y}年${dateobj.M}月${dateobj.D}日${dateobj.h}时${dateobj.m}分${dateobj.s}秒`
    return dateobj

}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//获取上次签到时间
export async function getLastsign(usr_qq) {
    //查询redis中的人物动作
    let time = await redis.get("xiuxian:player:" + usr_qq + ":lastsign_time");
    console.log(time);
    if (time != null) {
        let data = await shijianc(parseInt(time))
        return data;
    }
    return false;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//获取当前人物状态
export async function getPlayerAction(usr_qq) {
    //查询redis中的人物动作
    let arr = {};
    let action = await redis.get("xiuxian:player:" + usr_qq + ":action");
    action = JSON.parse(action);
    //动作不为空闲
    if (action != null) {
        //人物有动作查询动作结束时间
        let action_end_time = action.end_time;
        let now_time = new Date().getTime();
        if (now_time <= action_end_time) {
            let m = parseInt((action_end_time - now_time) / 1000 / 60);
            let s = parseInt(((action_end_time - now_time) - m * 60 * 1000) / 1000);
            arr.action = action.action;//当期那动作
            arr.time = m + "分" + s + "秒";//剩余时间
            return arr;
        }
    }
    arr.action = "空闲";
    return arr;
}
//---------------------------------------------分界线------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/**
 * 判断对象是否不为undefined且不为null
 * @param obj 对象
 * @returns obj==null/undefined,return false,other return true
 */
 export function isNotNull(obj) {
    if (obj == undefined || obj == null)
        return false;
    return true;
}

export function isNotBlank(value) {
    if (value ?? '' !== '') {
        return true;
    } else {
        return false;
    }
}

